<template>
  <div>
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>文章列表</span>
      </div>
      <!-- 搜索区域 -->
      <div class="search-box">
        <el-form :inline="true" :model="q">
          <el-form-item label="文章分类">
            <!--       v-model="q.cate_id"  双重绑定   -->
            <el-select v-model="q.cate_id" placeholder="请选择分类" size="small">
              <!-- 吧 item.id 传给 q.cate_id 发送请求获取数据列表的时候q.cate_id就是有值的 -->
              <el-option v-for="item  in cateList"
              :key="item.id" :label="item.cate_name" :value="item.id"></el-option>
              
            </el-select>
          </el-form-item>
          <el-form-item label="发布状态" style="margin-left: 15px;">
            <el-select v-model="q.state" placeholder="请选择状态" size="small">
              <el-option label="已发布" value="已发布"></el-option>
              <el-option label="草稿" value="草稿"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <!--                                       点击筛选 调用函数获取数据 -->
            <el-button type="primary" size="small" @click="getArticleList()">筛选</el-button>
            <!--                                       点击重置 先把  q.cate_id='' 清空 在调用获取列表函数-->
            <el-button type="info" size="small" @click="resetArticle">重置</el-button>
          </el-form-item>
        </el-form>
        <!-- 发表文章的按钮 -->
        <el-button type="primary" size="small" class="btn-pub" @click="showDialog=true" >发表文章</el-button>
      </div>
      <!-- 文章表格区域 -->
    <el-table :data="crticleList" style="width: 100%;" border stripe>

      <el-table-column label="文章标题" prop="title">
        <template #default='{row}'>
          <!-- {{row.title}} -->
        <el-link type='primary' @click="getArtDetail(row.id)" > {{row.title}} </el-link>
        </template>
      </el-table-column>

      <el-table-column label="文章分类" prop="cate_name"></el-table-column>
      <!-- 默认插槽 -->
      <el-table-column label="发表时间" prop="pub_date">
        <!-- 作用域插槽 -->
        <template #default='{row}'>
        <!-- {{row.pub_date}} -->
        <!-- 
          作用域插槽
            --vue的过滤器格式化数据
            --自定义函数格式化数据
         -->
        {{  formatData(row.pub_date) }}
        </template>
      </el-table-column>
      <el-table-column label="状态" prop="state"></el-table-column>
      <el-table-column label="操作">
        <template #default='{row}'>
        <el-button type="danger" size="mini"  @click="delArticle(row.id)"> 删除</el-button>
        </template>
      </el-table-column>
    </el-table>
         <!-- 分页功能 -->
      <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="q.pagenum"
      :page-sizes="[2,20,40,80,]"
      :page-size="q.pagesize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total">
    </el-pagination>

    </el-card>

    <!-- 发布文章的对话框 -->
    <el-dialog
     @close="removeData"
     title="发表文章" 
     :visible.sync="showDialog" 
     fullscreen
     :before-close="handleClose">
     <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
      <el-form-item label="文章标题" prop="title">
        <el-input v-model="ruleForm.title"></el-input>
      </el-form-item>
      <el-form-item label="文章分类" prop="cate_id">
        <el-select v-model="ruleForm.cate_id" placeholder="请选择文章分类" style=" width: 100%;" >
          <el-option 
           v-for="item in cateList" :key="item.id" 
           :label="item.cate_name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>

       <el-form-item label="文章内容" prop="content">
        <!-- 使用 v-model 进行双向的数据绑定 -->
         <quill-editor v-model="ruleForm.content"></quill-editor>
      </el-form-item>

      <!-- 图片封面 -->
      <el-form-item label="文章封面">
        <!-- 用来显示封面的图片 -->
        <img src="../../../assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef"  />
        <br />
        <!-- 文件选择框，默认被隐藏 -->
        <input 
        type="file" 
        style="display: none;" accept="image/*"
        ref="iptFile" @change="fileImg"  />
        <!-- 选择封面的按钮 -->
        <el-button type="text" @click="$refs.iptFile.click()"  >+ 选择封面</el-button>
      </el-form-item>
       <el-form-item >
       <el-button type="primary" @click="putArticle('已发布')" >发布</el-button>
       <el-button type="info" @click="putArticle('草稿')">存为草稿</el-button>
      </el-form-item>
     </el-form>
    </el-dialog>
    <!-- 显示文章详情对话框 -->
    <el-dialog title="文章预览" :visible.sync='showDeailDialog' width="80%">
      <h1 class="title">{{ artDetail.title }}</h1>
      <div class="info">
        <span>作者：{{ artDetail.nickname || artDetail.username }}</span>
        <span>发布时间：{{ formatData(artDetail.pub_date) }}</span>
        <span>所属分类：{{ artDetail.cate_name }}</span>
        <span>状态：{{ artDetail.state }}</span>
      </div>
      
      <!-- 分割线 -->
      <el-divider></el-divider>

      <img :src="'http://big-event-vue-api-t.itheima.net' + artDetail.cover_img" alt="" />

      <div v-html="artDetail.content"></div>
    </el-dialog>
  </div>
</template>

<script>
// 时间格式转换 Day.js中文网      1.装包  yarn add  dayjs
//2.导入
 import dayjs from 'dayjs'
 //3.使用 dayjs().format()
import defaultImg  from'@/assets/images/cover.jpg'
/* webpack 将  vue less js 打包生成 相应的js文件和css文件
webpack 模板中引入的图片或 import 引入的图片,会自动生成相应的图片文件或者 base64格式的字符串
----如果图片小于8kb ,那么 webpack 将图片直接生成相应的base64格式的字符串
----如果图片大于8kb ,那么 webpack 将图片直接生成相应的图片文件
defaultImg =====> /img/cover.54bfb07c.jpg  */
//  console.log('defaultImg',defaultImg)
export default {
  name: 'ArtList',
  created(){
    //页面加载就调用  获取分类数据
    this.getArtCateList()
    //页面加载就调用 获取文章列表数据
    this.getArticleList()
  },
  data() {
    return {
      //准备的表单的数据    发表文章
      ruleForm:{
        title:'',
        cate_id:'',
        content:'',
        state:'草稿',   //存储文章状态  已发布 || 草稿
        cover_img:null  //存储文件对象
      },
      crticleList:[], //保存 获取的文章列表分类数据
      cateList:[],  //保存文章分类的数据
      //做表单校验
      rules:{
        title:[
           { required: true, message: '请输入文章名称', trigger: 'blur' },
           { min:1,max:30, message: '请输入长度1--30的字符', trigger: 'blur' },
        ],
        cate_id:[
           { required: true, message: '请输入文章分类', trigger: 'blur'||'change' },
        ],
        content:[
           { message: '请输入文章内容', trigger: 'blur' },
        ]
      },
      showDeailDialog:false, // 控制文章详情的显示与隐藏
      showDialog:false, //控制发布文章的对话框的显示和隐藏
      // 查询参数对象
      q: {
        pagenum: 1, //当前页码值
        pagesize: 2,//每页要显示的条数
        cate_id: '',//文章的分类
        state: ''//文章的状态
      },
      total:0,//保存文章的总数
      artDetail:{} //保存获取到的文章详情数据
    }
  },
  methods:{
    //  dialog 对话框关闭 执行里面的重置代码
    removeData(){
          //清空图片数据
        this.ruleForm.cover_img  = null
        //复原 ruleForm  里的数据
        //解决 重复上传一张图片 不显示图片的问题   this.$refs.iptFile.value  = null
        this.$refs.iptFile.value  = null
        this.ruleForm.state  = '草稿'
        //清空显示图片
        this.$refs.imgRef.src  = defaultImg
        //清空表单数据
        this.$refs.ruleForm.resetFields();
    },
    //点击删除文章 1. 绑定点击事件函数
    delArticle(id){
      // 2.提示询问框
      this.$confirm('确定删除次条数距么').then(async ()=>{
        //3.发送请求数据实现删除
        const {data:res} =  await this.$axios.delete('/my/article/info',{params:{id,}})
        if(res.code !==0)  return
        this.$message.success(res.message)
        //判断 如果当前页面只剩最后一条数据 
        if(this.crticleList.length >= 1){
          //让this.q.pagenum--
          this.q.pagenum-- 
        }
          //4.重新渲染数据
        this.getArticleList()
      }).catch((err)=>{console.log(err)})
    },
    //获取对应文章详情的数据
    async getArtDetail(id){
      const {data:res} =  await this.$axios('/my/article/info', {params:{id,}})
      if(res.code != 0)return
      // console.log(res)
      this.artDetail  = res.data
      this.showDeailDialog = true
    },
     // 重置功能
    resetArticle(){
      this.q ={
        pagenum: 1, //当前页码值
        pagesize: 2,//每页要显示的条数
        cate_id: '',//文章的分类
        state: ''//文章的状态
      }
      this.getArticleList()
    },
      //显示的每页多少条  当前页面显示的条数进行切换时触发 val====>每页显示的条数
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`);
      //当改变每页显示多少条的时候  让他从第一页开始
       this.q.pagenum  = 1
      //改变请求参数 q.pagesize 的值
      this.q.pagesize= val
      //重新发送请求,重新获取数据 渲染数据
      this.getArticleList()
    },
      //显示当前第几页  当前的页面值进行切换的时候触发 val====>当前的页码值
    handleCurrentChange(val) {
      //改变请求参数 q.pagenum 的值
      console.log(`当前页: ${val}`);
      this.q.pagenum  = val
      //重新发送请求,重新获取数据 渲染数据
      this.getArticleList()
    },

    //格式化时间
    formatData(time){
      //使用 Day.js 进行时间的格式化
      //必须要 return 
      return  dayjs(time).format('YYYY-MM-DD HH:mm:ss')
    },
    //获取文章列表数据
    async  getArticleList(){
      const {data:res} =await this.$axios('/my/article/list',{params:this.q})
      // console.log(res)
      if(res.code !=0)return
      this.crticleList = res.data
      this.total =  res.total
    },
    //关闭对话框给一个弹窗提示
    handleClose(){
      this.$confirm('你确定要关闭么?关闭会导致当前所修改的数据丢失').then(()=>{
     
        this.showDialog=false
        
      }).catch(err=>{
        console.log(err)
      })
    },
    // 获取文章分类的数据
    async  getArtCateList(){
      const {data:res}  =await  this.$axios('/my/cate/list')
      if(res.code != 0 )return
      // console.log(res)
      this.cateList = res.data
    },
    // 获取选择的图片
    fileImg(e){
      // console.log(e)
      const files  = e.target.files
      if(files.length){
        // 选择了图片
        this.ruleForm.cover_img = files[0]

        // console.log('files[0]',files[0])
        // URL.createObjectURL('需要转换的内容') 将图片文件直接存储到程序的内存中,然后返回一个可以访问的链接地址
        const url= URL.createObjectURL(files[0])
        // url blob:http://localhost:10088/eb0ca844-0ee1-4e7c-a016-ac3e7c251f62
        // console.log('url',url)
        this.$refs.imgRef.src = url
        
      }else{
        // 没有选择图片
        //将img的src设置为默认的图片地址
        this.$refs.imgRef.src  =defaultImg
        this.ruleForm.cover_img = null
      }
    },
    //发布文章
    putArticle(state){
      this.ruleForm.state = state
      // console.log(this.ruleForm.state)
      this.$refs.ruleForm.validate(async (valid)=>{
        if(!valid)  return  //兜底校验失败
        //手动校验文章的封面是否上传
        if(this.ruleForm.cover_img ===  null){
          //没有上传 给一个弹窗提示
          this.$message.error('请上传文章封面')
        }else{
          //发送请求实现发布文章
          //将 this.ruleForm 对象转换为  FormData格式
          //注意点: 如果发送请求时携带的参数有文件对象,那么就需要将携带的参数转化为 FormData 格式在携带
          const fd =  new FormData()// FormData 空实例对象
        /*   fd.append('title',this.ruleForm.title)
          fd.append('cate_id',this.ruleForm.cate_id)
          fd.append('content',this.ruleForm.content)
          fd.append('cover_img',this.ruleForm.cover_img)
          fd.append('state',this.ruleForm.state)

          fd.forEach((key,value)=>{
            console.log(`key:${key}=====>value:${value}`)
          }) */
          // 简介写法 优化
          Object.keys(this.ruleForm).forEach(key=>{
            // console.log('key',key, 'this.ruleForm[key]',this.ruleForm[key])
            //key获取键 (属性名 )     this.ruleForm[key]获取值  (属性值)
            fd.append(key,this.ruleForm[key])
          })


          const {data:res}  = await this.$axios.post('/my/article/add',fd)
          if(res.code !=0)return this.$message.error(res.message)
          this.$message.success(res.message)
          //获取文章列表的数据重新渲染页面
           this.getArticleList()
          /*  //清空图片数据
           this.ruleForm.cover_img  = null
           //复原 ruleForm  里的数据
           this.ruleForm.state  = '草稿'
           //清空显示图片
           this.$refs.imgRef.src  =defaultImg
           //清空表单数据
           this.$refs.ruleForm.resetFields(); */
          //关闭对话框
           this.showDialog=false
        }
      })
    }
  }
  
}
</script>

<style lang="less" scoped>
.search-box {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  .btn-pub {
    margin-top: 5px;
  }
}
// 设置图片封面的宽高
.cover-img {
  min-width: 400px;
  min-height: 280px;
  object-fit: cover;
}

 /deep/.ql-editor{
  //最小300px 内容多会撑大
  min-height: 300px !important;
 }
</style>
